import { assign } from 'lodash';
import 'whatwg-fetch';
import { API_ROOT } from 'config/app';
import auth from 'components/common/auth';

function buildQueryString(params) {
  if (!params) return '';

  const keys = Object.keys(params);

  if (keys.length === 0) return '';

  const components = keys.map(
    key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`
  );

  return `?${components.join('&')}`;
}

function prepareRequest(path, method, parameters) {
  const withBody = method.toUpperCase() !== 'GET';

  const bodyString = withBody ? JSON.stringify(parameters) : null;

  const queryString = withBody ? '' : buildQueryString(parameters);

  const headers = {
    Authorization: `Bearer ${auth.getAccessToken()}`,
    Accept: 'application/json',
    'Content-Type': 'application/json',
  };

  const uri = API_ROOT + path + queryString;
  const body = bodyString;

  return new global.Request(uri, {
    method,
    headers,
    timeout: 2,
    body,
    mode: 'cors',
  });
}

function parseApiResponse(response) {
  return response.text().then(text => {
    try {
      const json = JSON.parse(text);
      return { json, response };
    } catch (e) {
      return {
        json: text,
        response,
      };
    }
  });
}

export const CALL_BOOK_API = Symbol('Call BOOK API');

export default () => next => action => {
  const JQAPI = action[CALL_BOOK_API];
  if (typeof JQAPI === 'undefined') {
    return next(action);
  }

  const { types, uri, method } = JQAPI;
  const body = JQAPI.body || {};
  const [requestType, successType, failureType] = types;

  // 添加Loading处理
  next(
    assign({}, action, {
      type: 'SET_LOADING',
      payload: {
        scope: requestType,
        loading: true,
      },
    })
  );

  /*
  if (!auth.loggedIn()) {
    return next(
      assign({}, action, {
        type: failureType,
        code: 'token.timeout',
        msg: '登录超时',
      })
    );
  }
  */

  function checkIfRequestIsFailed({ json, response }) {
    if (!response.ok) {
      return Promise.reject(json);
    }
    return json;
  }

  // 要放在checkIfRequestIsFailed前执行
  function handleLoadingDone(response) {
    next(
      assign({}, action, {
        type: 'SET_LOADING',
        payload: {
          scope: requestType,
          loading: false,
        },
      })
    );
    return response;
  }

  function handleRequestSucc(response) {
    return next(
      assign({}, action, {
        type: successType,
        response,
      })
    );
  }

  function handleError(error) {
    return next(
      assign({}, action, {
        type: failureType,
        code: error.code || 'unknown.error',
        msg: error.msg || 'unknown.error',
      })
    );
  }

  return global
    .fetch(prepareRequest(uri, method, body))
    .then(parseApiResponse)
    .then(handleLoadingDone)
    .then(checkIfRequestIsFailed)
    .then(handleRequestSucc, handleError);
};
